package com.xwaf.platform.system.provider.serviceimpl.pay;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.xwaf.platform.common.api.constants.BaseConstants;
import com.xwaf.platform.system.api.entity.DataBase;
import com.xwaf.platform.system.api.entity.pay.Apply;
import com.xwaf.platform.system.api.entity.pay.ApplyConfig;
import com.xwaf.platform.system.api.entity.pay.Order;
import com.xwaf.platform.system.api.request.three.AliProductRequest;
import com.xwaf.platform.system.api.service.pay.AliService;
import com.xwaf.platform.system.api.util.AliPayConfig;
import com.xwaf.platform.system.provider.dao.pay.ApplyConfigDao;
import com.xwaf.platform.system.provider.dao.pay.ApplyDao;
import com.xwaf.platform.system.provider.dao.pay.OrderDao;

@Service(value = "aliService")
public class AliServiceImpl implements AliService {

	private static final Logger logger = LoggerFactory.getLogger(AliServiceImpl.class);
	@Autowired
	private OrderDao orderDao;

	@Autowired
	private ApplyDao applyDao;

	@Autowired
	private ApplyConfigDao applyConfigDao;

	@Override
	@Transactional(readOnly = false, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public String aliPayPc(AliProductRequest product) {
		logger.info("支付宝PC支付下单");
		// 获取应用参数
		Map<String, String> maps = getPayParameter();
		// 支付相关
		AlipayClient alipayClient = new DefaultAlipayClient(maps.get("open_api_domain"), maps.get("appid"),
				maps.get("private_key"), AliPayConfig.PARAM_TYPE, AliPayConfig.CHARSET, maps.get("alipay_public_key"),
				AliPayConfig.SIGN_TYPE);
		AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
		String returnUrl = "http://www.h5.com";
		alipayRequest.setReturnUrl(returnUrl);// 前台通知
		alipayRequest.setNotifyUrl(maps.get("notify_url"));// 后台回调
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", product.getOutTradeNo());
		bizContent.put("total_amount", "0.01");// 订单金额:元
		bizContent.put("subject", "香蕉五毛一根");// 订单标题
		bizContent.put("seller_id", maps.get("pid"));// 实际收款账号，一般填写商户PID即可
		bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");// 电脑网站支付
		bizContent.put("body", "香蕉五毛一根");
		/**
		 * 这里有三种模式可供选择 如果在系统内支付，并且是弹出层支付，建议选择模式二、其他模式会跳出当前iframe(亲测有效)
		 */
		bizContent.put("qr_pay_mode", "2");
		bizContent.put("passback_params", product.getOutTradeNo());// 回传单号
		String biz = bizContent.toString().replaceAll("\"", "'");
		alipayRequest.setBizContent(biz);
		logger.info("业务参数:" + alipayRequest.getBizContent());
		String form = BaseConstants.FAIL.getCode();
		try {
			form = alipayClient.pageExecute(alipayRequest).getBody();
			Order order = new Order();
			order.setId(DataBase.getDataBaseId(DataBase.OR));
			order.setOrderNo(product.getOutTradeNo());
			order.setTotalFee(1L);// 分
			order.setApplyId(maps.get("applyId"));
			order.setCreateBy("1");
			order.setUpdateBy("1");
			order.setCreateTime(new Date());
			order.setUpdateTime(new Date());
			order.setForm(form);
			orderDao.insert(order);
		} catch (AlipayApiException e) {
			logger.error("支付宝构造表单失败", e);
		}
		return form;
	}

	@Override
	@Transactional(readOnly = false, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public String aliPayMobile(AliProductRequest product) {
		logger.info("支付宝手机支付下单");
		// 获取应用参数
		Map<String, String> maps = getPayParameter();
		// 支付相关
		AlipayClient alipayClient = new DefaultAlipayClient(maps.get("open_api_domain"), maps.get("appid"),
				maps.get("private_key"), AliPayConfig.PARAM_TYPE, AliPayConfig.CHARSET, maps.get("alipay_public_key"),
				AliPayConfig.SIGN_TYPE);
		AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
		String returnUrl = "http://www.h5.com";
		alipayRequest.setReturnUrl(returnUrl);// 前台通知
		alipayRequest.setNotifyUrl(maps.get("notify_url"));// 后台回调
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", product.getOutTradeNo());
		bizContent.put("total_amount", "0.01");// 订单金额:元
		bizContent.put("subject", "香蕉五毛一根");// 订单标题
		bizContent.put("seller_id", maps.get("pid"));// 实际收款账号，一般填写商户PID即可
		bizContent.put("product_code", "QUICK_WAP_PAY");// 手机网页支付
		bizContent.put("body", "香蕉五毛一根");
		bizContent.put("passback_params", product.getOutTradeNo());// 回传单号
		String biz = bizContent.toString().replaceAll("\"", "'");
		alipayRequest.setBizContent(biz);
		logger.info("业务参数:" + alipayRequest.getBizContent());
		String form = BaseConstants.FAIL.getCode();
		try {
			form = alipayClient.pageExecute(alipayRequest).getBody();
			Order order = new Order();
			order.setId(DataBase.getDataBaseId(DataBase.OR));
			order.setOrderNo(product.getOutTradeNo());
			order.setTotalFee(1L);// 分
			order.setApplyId(maps.get("applyId"));
			order.setCreateBy("2");
			order.setUpdateBy("2");
			order.setCreateTime(new Date());
			order.setUpdateTime(new Date());
			order.setForm(form);
			orderDao.insert(order);
		} catch (AlipayApiException e) {
			logger.error("支付宝构造表单失败", e);
		}
		return form;
	}

	private Map<String, String> getPayParameter() {
		Wrapper<Apply> wrapper1 = new EntityWrapper<Apply>();
		wrapper1.where("pay_company_key ={0} and status ='1' ", "ZFB");
		List<Apply> applies = applyDao.selectList(wrapper1);
		checkArgument(applies != null && applies.size() > 0, "操作失败,没有查询到应用");
		int i = 1;
		if (applies.size() == 1) {
			i = new Random().nextInt(applies.size());
		} else {
			i = new Random().nextInt(applies.size() - 1);
		}
		Apply apply = applies.get(i);
		Wrapper<ApplyConfig> wrapper2 = new EntityWrapper<ApplyConfig>();
		wrapper2.where("apply_id = {0}", apply.getId());
		List<ApplyConfig> applyConfigs = applyConfigDao.selectList(wrapper2);
		checkArgument(applyConfigs != null && applyConfigs.size() > 0, "操作失败,应用参数没有进行配置");
		Map<String, String> maps = new HashMap<String, String>();
		for (ApplyConfig applyConfig : applyConfigs) {
			maps.put(applyConfig.getKey(), applyConfig.getValue());
		}
		maps.put("applyId", apply.getId());
		if (maps.get("open_api_domain") == null || maps.get("appid") == null || maps.get("private_key") == null
				|| maps.get("alipay_public_key") == null || maps.get("pid") == null || maps.get("notify_url") == null) {
			checkArgument(false, "操作失败,支付参数配置不完整");
		}
		return maps;
	}
}
